package XunChunCPU.IF

import chisel3._
import XunChunCPU.common.CommonConfig._

class PC extends Module {
    val io = IO(new Bundle{
        // 握手相关
        val ready_in = Input(Bool())            // 从译码阶段进来的ready
        val valid_out = Output(Bool())
        // 访存信号，除pc和req外信号都直接指定，因为IF阶段确定读32位
        val npc = Output(UInt(instrAddrLen.W))  // 根据NPC_Type和pcImm输出npc到Ram
        val pc = Output(UInt(instrAddrLen.W))   // 输出pc
        // 其他信号
        val NPC_Type = Input(Bool())
        val pcImm = Input(UInt(instrLen.W))
        val stall = Input(Bool())               // 取值暂停信号的汇总
    })
    // !!!如果阻塞了，将使用输出的pc作为addr
    val pcreg = RegInit(0x7ffffffCL.U(instrAddrLen.W))

    when(io.ready_in && !io.stall){
        // 译码阶段准备好了
        when(io.NPC_Type === NPC_4) {
            pcreg := io.pc + 4.U
        }.otherwise{
            pcreg := io.pcImm
        }
        io.valid_out := true.B
    }.otherwise{
        // 译码阶段没有准备好
        pcreg := io.pc
        io.valid_out := false.B
    }
    // npc组合逻辑
    when(io.NPC_Type === NPC_4){
        io.npc := io.pc + 4.U
    }.otherwise{
        io.npc := io.pcImm
    }
    io.pc := pcreg

}